home *** CD-ROM | disk | FTP | other *** search
/ Best of Shareware / Best of PC Windows Shareware 1.0 - Wayzata Technology (7111) (1993).iso / mac / DOS / CAD_CAM / A7221V1B / COMIO.C < prev    next >
C/C++ Source or Header  |  1992-03-12  |  7KB  |  223 lines

  1. /*
  2.    Module:  comio.c
  3.    Date:    3/9/92
  4.    Version: 1.0b
  5.    Author:  Dave Lutz
  6.    Email:   lutz@psych.rochester.edu
  7.    Copyright: 1992 University of Rochester, Psychology Dept.
  8.  
  9.    Disclaimer:  This software is distributed free of charge.  As such, it
  10.                 comes with ABSOLUTELY NO WARRANTY.  The user of the software
  11.                 assumes ALL RISKS associated with its use.
  12.  
  13.                 Your rights to modify and/or distribute this software are
  14.                 outlined in the file SEND7221.DOC.
  15.  
  16.    Purpose: This module provides the functions needed to do serial io
  17.             operations on an IBM compatible PC.  Functions provided are
  18.             cominit, comin, comout, comstat, comlstat.
  19.  
  20. */
  21.  
  22. #include "comio.h"
  23.  
  24. #ifndef NULL
  25. #  define NULL 0
  26. #endif
  27.  
  28. /* dos interrupt and function codes */
  29. #define SERIAL_IO 0x14
  30. #define INIT      0x00
  31. #define SEND      0x01
  32. #define RECV      0x02
  33. #define STAT      0x03
  34.  
  35.  
  36. /*
  37.    Function: cominit
  38.    Purpose:  set up a COMPORT for subsequent io operations
  39.  
  40.    Pre: cpp is a pointer to a COMPORT data structure.
  41.         portdes is one of the port designators defined in comio.h
  42.         config is the desired configuration for the com port, and was
  43.         obtained by combining the configuration constants defined in
  44.         comio.h with a bitwise or.
  45.         timeout is the number of seconds to wait for the first character
  46.         during an input operation.
  47.  
  48.    Post: The portdes, config, and timeout paramaters are transferred to the 
  49.          cpp structure.
  50.          A dos interrupt is called to open and configure the desired
  51.          serial port.
  52.          The bitmapped status of the port is returned.
  53.  
  54.          The status of the port can be determined by comparing it to the
  55.          LCS_* and MCS_* values defined in comio.h.  For example:
  56.  
  57.                 (MCS_DSRSTAT & retval) 
  58.          
  59.          will be nonzero if Modem Control Status indicates Data Set Ready.
  60. */
  61.  
  62. unsigned cominit (cpp, portdes, config, timeout)
  63.    COMPORT *cpp;
  64.    int portdes;
  65.    unsigned config;
  66.    time_t timeout;
  67. {
  68.    /* transfer the configuration options to the appropriate registers */
  69.    cpp->inregs.x.dx = portdes;
  70.    cpp->inregs.h.al = config;
  71.    cpp->timeout     = timeout;
  72.  
  73.    /* set up for an init call */
  74.    cpp->inregs.h.ah = INIT;
  75.  
  76.    /* perform the call, returning the contents of the ax register */
  77.    return (int86(SERIAL_IO,&(cpp->inregs),&(cpp->outregs)));
  78. }
  79.  
  80.  
  81.  
  82. /*
  83.    Function: comin
  84.    Purpose:  read a block of characters from the serial port.
  85.  
  86.    Pre: cpp is a pointer to a COMPORT structure.
  87.         cpp has been prepared via a call to cominit.
  88.         Nobody has been mucking around with the internals of the
  89.         cpp structure...
  90.         buff is a pointer to storage for the bytes read from the
  91.         port.  There is enough storage for max characters.
  92.         max is the maximum number of chars to read.
  93.         term is a character which, when read, signals the end of
  94.         the input stream.
  95.         If there is no real term character, term = -1.
  96.  
  97.    Post:  Characters are read from the serial port and stored in buff
  98.           until: max chars have been read, the term char is read, or an
  99.           I/O error occurs.
  100.           The function will wait the predefined (by cominit) number of 
  101.           seconds for the first character to appear.
  102.           After the first character appears, the remaining chars are
  103.           expected to follow immediately.  If they don't, the function
  104.           will exit.
  105.           The number of characters actually read is returned.
  106.           The serial port should be checked with comlstat to determine
  107.           if an error has occurred.
  108. */
  109. int comin (cpp, buff, max, term)
  110.    COMPORT *cpp;
  111.    char *buff;
  112.    int max,
  113.        term;
  114. {
  115.    time_t starttime;
  116.    int readcnt = 0;
  117.    unsigned testmask;
  118.    testmask = (LCS_RDR | LCS_OVRN | LCS_PAR | LCS_FRM );
  119.  
  120.    /* bail out if they don't really want to read anything */
  121.    if (max == 0)
  122.       return (readcnt);
  123.  
  124.    /* wait cpp->timeout seconds for the first char to appear (or an error) */
  125.    starttime = time ((time_t *)NULL);
  126.    cpp->inregs.h.ah = STAT;
  127.    while ((int86(SERIAL_IO,&(cpp->inregs),&(cpp->outregs)) & testmask) == 0)
  128.       if (time ((time_t *)NULL) > starttime + cpp->timeout)
  129.          return (readcnt);
  130.  
  131.    /* make sure the while loop terminated due to "Receive Data Ready" */
  132.    if ((cpp->outregs.x.ax & LCS_RDR) != LCS_RDR)
  133.       return (readcnt);
  134.  
  135.    /* read from the port up to max chars, an error, or a term char */
  136.    cpp->inregs.h.ah = RECV;
  137.    do {
  138.       (void) int86(SERIAL_IO,&(cpp->inregs),&(cpp->outregs));
  139.       *buff = cpp->outregs.h.al;
  140.    } while ((cpp->outregs.h.ah == 0) && (++readcnt < max) && (*buff++ != term));
  141.    return (readcnt);
  142. }
  143.  
  144.  
  145.  
  146. /*
  147.    Function: comout
  148.    Purpose:  Send a block of characters through the serial port.
  149.  
  150.    Pre: cpp is a pointer to a COMPORT structure.
  151.         cpp has been prepared via a call to cominit.
  152.         buff is a pointer to the block of chars to be transmitted.
  153.         buffcnt is the number of chars to send.
  154.  
  155.    Post: An attempt is made to send the block of chars through the
  156.          serial port.
  157.          The number of chars actually sent is returned.
  158.          If all bytes were not sent, it should be possible to determine
  159.          the reason by making a call to comlstat.
  160. */
  161. int comout (cpp, buff, buffcnt)
  162.    COMPORT *cpp;
  163.    char *buff;
  164.    int buffcnt;
  165. {
  166.    int sentcnt = 0;
  167.    cpp->inregs.h.ah = SEND;
  168.    while (sentcnt < buffcnt) {
  169.       cpp->inregs.h.al = *buff++;
  170.       if ((int86(SERIAL_IO,&(cpp->inregs), &(cpp->outregs)) & LCS_TIM) != 0)
  171.          break;
  172.       sentcnt++;
  173.    }
  174.    return (sentcnt);
  175. }
  176.  
  177.  
  178.  
  179. /*
  180.    Function: comstat
  181.    Purpose:  Report the current status of the com port.
  182.  
  183.    Pre: cpp is a pointer to a COMPORT structure.
  184.         cpp has been set up via a call to comopen.
  185.         Nobody has been mucking around with the internals of the
  186.         cpp structure...
  187.  
  188.    Post:  A DOS interrupt is called to check the status of the port
  189.           specified in *cpp.
  190.           The status of the port is returned as a bitmapped value.
  191.           This value can be interpreted by comparing it to the LCS_*
  192.           and MCS_* masks defined in comio.h
  193. */
  194. unsigned comstat (cpp)
  195.    COMPORT *cpp;
  196. {
  197.    cpp->inregs.h.ah=STAT;
  198.    /* perform the call, returning the value of the AX register */
  199.    return (int86(SERIAL_IO, &(cpp->inregs), &(cpp->outregs)));
  200. }
  201.  
  202.  
  203. /*
  204.    Function: comlstat
  205.    Purpose:  Report the status of the com port as it was after the last
  206.              call to one of the other comio functions.
  207.  
  208.    Pre: cpp is a pointer to a COMPORT stucture.
  209.         cpp has been set up via a call to comopen.
  210.         Nobody has been mucking around with the internals of the
  211.         cpp structure...
  212.  
  213.    Post: The last status of the com port is returned as a bitmapped
  214.          value.
  215.          This value can be interpreted by comparing it to the LCS_*
  216.          and MCS_* masks defined in comio.h
  217. */
  218. unsigned comlstat (cpp)
  219.    COMPORT *cpp;
  220. {
  221.    return (cpp->outregs.x.ax);
  222. }
  223.